// promise 限流  封装
// 不要用流程性的写法 写函数，写类 

class Limit{
    constructor(n){
        this.limit = n;   // 限流的数量
        this.count=0;   // 正在执行的数量
        // promise 执行前 this.count++  await this.count--
        // promise执行完后this.count <this.limit  this.query 出队
        this.query=[];
    }
    enqueue(fn){
        // 入队
        // return new Promise((resolve,reject)=>{
        //     this.query.push({fn,resolve,reject})
        // })
        this.query.push(fn)
    }
    dequeue(){
        // 出队执行
        if(this.count < this.limit && this.query.length){
            // const {fn,resolve,reject}=this.query.shift();
            const fn=this.query.shift();
            // this.run(fn).then(resolve).catch(reject);
            this.run(fn);
        }
    }
    async run(fn){
        // 运行
        const value=await fn();
        this.count--;
        this.dequeue();
        return value;
    }
    build(fn){
        // 分支
        if(this.count<this.limit){
            this.count++;
            return this.run(fn);
        }
        else{
            return this.enqueue(fn);
        }
    }
}

// 100个promise => map[[3],[3]]
Promise.map=function(list,fn,{concurrency}){
    const limit=new Limit(concurrency);
    return Promise.all(list.map(        // 接受一个Promise数组 直到所有Promise执行完将所有的结果返回
            (item)=>{
                // fn 执行或入队？
                return limit.build(()=>fn(item))
            })
        );  
}

Promise.map(
    ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o'] ,
    (name)=>{
        return new Promise(resolve=>{
            setTimeout(() => {
                console.log(name,'++==');
                resolve(name);
            }, 1000);
        })
    },
    {
        concurrency:3
    });